package proxy

import (
	"errors"
	"strings"

	"github.com/nacos-group/nacos-sdk-go/model"
)

type FilterInstanceFunc func(model.Instance, string) bool

func choose(serviceName, serviceGroup string) (string, int, error) {
	service, ok := discoveryClient.getService(serviceName)
	if !ok {
		return "", 0, errors.New("cannot get service")
	}
	hosts := service.Hosts
	if len(hosts) == 0 {
		return "", 0, errors.New("service empty")
	}

	if isMasterGroup(serviceGroup) {
		fallback := func (model.Instance, string) bool {
			return false
		}
		return doChoose(hosts, serviceGroup, filterMasterGroup, fallback)
	} else {
		return doChoose(hosts, serviceGroup, filterNamedGroup, filterMasterGroup)
	}
}

func isMasterGroup(serviceGroup string) bool {
	return serviceGroup == "" || strings.EqualFold(serviceGroup, NacosMasterGroup)
}

func filterMasterGroup(instance model.Instance, group string) bool {
	instanceGroup, ok := instance.Metadata[NacosMetadataGroup]
	return !ok || instanceGroup == "" || instanceGroup == NacosMasterGroup
}

func filterNamedGroup(instance model.Instance, group string) bool {
	instanceGroup, ok := instance.Metadata[NacosMetadataGroup]
	return ok && instanceGroup == group
}

func doChoose(hosts []model.Instance, group string, 
	filter FilterInstanceFunc, 
	fallback FilterInstanceFunc) (string, int, error) {
	for _, instance := range hosts {
		if filter(instance, group) {
			return instance.Ip, int(instance.Port), nil
		}
	}
	for _, instance := range hosts {
		if fallback(instance, group) {
			return instance.Ip, int(instance.Port), nil
		}
	}
	return "", 0, errors.New("empty")
}